import json
import os
import tempfile

from playwright.sync_api import Browser, BrowserContext
from playwright.sync_api import sync_playwright

from config import USERNAME, PASSWORD, LOGIN_URL, SESSION_STORAGE_PATH, BASE_URL


def get_session_path():
    """获取会话文件路径，确保目录可写"""
    session_path = SESSION_STORAGE_PATH
    if not os.path.isabs(session_path):
        session_path = os.path.abspath(session_path)

    # 确保目录存在且有写入权限
    session_dir = os.path.dirname(session_path)
    try:
        os.makedirs(session_dir, exist_ok=True)
        # 测试写入权限
        test_file = os.path.join(session_dir, "test_write.tmp")
        with open(test_file, 'w') as f:
            f.write("test")
        os.remove(test_file)
        return session_path
    except (PermissionError, OSError):
        # 如果默认目录没有权限，使用临时目录
        temp_dir = os.path.join(tempfile.gettempdir(), "playwright_sessions")
        os.makedirs(temp_dir, exist_ok=True)
        return os.path.join(temp_dir, "storage_state.json")


def login_and_save_session(playwright):
    """执行登录并保存会话状态（使用传入的playwright实例）"""
    browser = playwright.chromium.launch(headless=False)
    context = browser.new_context()
    page = context.new_page()

    try:
        # 执行登录
        page.goto(LOGIN_URL)
        page.get_by_placeholder("账号").fill(USERNAME)
        page.get_by_placeholder("密码").fill(PASSWORD)
        page.get_by_role("button", name="登录").click()

        # 等待登录完成
        page.wait_for_url(f"{BASE_URL}/#/**", timeout=15000)
        page.wait_for_selector("div:has-text('客户管理中心')", timeout=8000)
        print("登录成功")

        # 保存会话状态
        session_path = get_session_path()
        session_dir = os.path.dirname(session_path)
        os.makedirs(session_dir, exist_ok=True)

        context.storage_state(path=session_path)
        print(f"会话状态已保存到: {session_path}")
        return True

    except Exception as e:
        print(f"登录过程中出错: {e}")
        return False
    finally:
        context.close()
        browser.close()


def is_session_valid():
    """检查保存的会话是否有效"""
    session_path = get_session_path()

    if not os.path.exists(session_path):
        return False

    try:
        with open(session_path, 'r', encoding='utf-8') as f:
            data = json.load(f)
            return bool(data.get('cookies')) or bool(data.get('origins'))
    except:
        return False


def create_context_with_session(playwright) -> tuple[BrowserContext, Browser]:
    """使用保存的会话创建浏览器上下文"""
    # 检查会话是否有效
    if is_session_valid():
        try:
            browser = playwright.chromium.launch(headless=False)
            context = browser.new_context(storage_state=get_session_path())

            # 验证会话是否有效
            page = context.new_page(viewport={'width': 1920, 'height': 1080})
            page.goto(f"{BASE_URL}/#/")
            page.wait_for_timeout(3000)

            if page.query_selector("div:has-text('客户管理中心')"):
                print("使用保存的有效会话")
                page.close()
                return context, browser

            page.close()
            context.close()
            browser.close()
        except Exception as e:
            print(f"加载会话时出错: {e}")

    # 需要重新登录
    print("需要重新登录...")
    if login_and_save_session(playwright):
        browser = playwright.chromium.launch(headless=False)
        context = browser.new_context(storage_state=get_session_path())
        return context, browser

    # 如果登录失败，创建全新的上下文
    print("登录失败，创建新的浏览器上下文")
    browser = playwright.chromium.launch(headless=False)
    context = browser.new_context()
    return context, browser


if __name__ == '__main__':
    with sync_playwright() as playwrigt:
        create_context_with_session(playwrigt)
